package src.javaStudy.inherit;

/**
 * @program: AlgorithmTest
 * @description:
 * 向上转型例子
 *  一般的声明方式 父类F f = new 子类c（继承父类F的）();
 *  f此时已经转型为父类F原来的子类c的方法就不能用了。但是还是会以子类的重写方法为主。
 *  注意：向上转型不要强制转型。向上转型后父类的引用所指向的属性是父类的属性，
 *  如果子类重写了父类的方法，那么父类引用指向的或者调用的方法是子类的方法,这个叫动态绑定。
 *  向上转型后父类引用不能调用子类自己的方法，就是父类没有但是子类的方法，如果调用不能编译通过，比如子类的speak方法。
 *
 *  非要调用子类的属性呢？如果不向下转型就需要给需要的属性写getter方法。
 *  非要调用子类扩展的方法，比如speak方法，就只能向下转型了。
 *
 *  向下转型需要考虑安全性，如果父类引用的对象是父类本身，那么在向下转型的过程中是不安全的，编译不会出错，
 *  但是运行时会出现java.lang.ClassCastException错误。
 *  它可以使用instanceof来避免出错此类错误即能否向下转型，
 *  只有先经过向上转型的对象才能继续向下转型。
 *
 *          Human h = new Male();// 向上转型
 *          Human h1 = new Human();
 *          //h.speak();此时需要向下转型，否则不能调用speak方法。
 *          Male m = (Male) h;
 *          m.speak();
 *          Male m1 = (Male)h1;
 *          m1.speak();    此时会出现运行时错误，所以可以用instanceOF判断
 *          if(h1 instanceof Male){
 *          Male m1=(Male)h1;
 *          m1.speak();
 *
 * @author: powerWriter
 * @create: 2019-06-16 11:51
 **/
public class Humen {

    public void sleep() {
        System.out.println("Human sleep..");
    }

    public static void main(String[] args) {
        Humen h = new Male();// 向上转型
        h.sleep();
        Male m = new Male();// 干嘛要向上转型
        m.sleep();
        m.speak();
        //h.speak();//此方法不能编译，报错说Human类没有此方法，因为已经向上转型，子类的方法不能用了
    }
}

class Male extends Humen {
    @Override
    public void sleep() {
        System.out.println("Male sleep..");
    }

    public void speak() {
        System.out.println("I am Male");
    }
}

class Female extends Humen {
    @Override
    public void sleep() {
        System.out.println("Female sleep..");
    }

    public void speak() {
        System.out.println("I am Female");
    }
}